package cn.iocoder.yudao.module.ai.service.dataset;

import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
import cn.iocoder.yudao.framework.exception.BusinessException;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.ai.constant.DicConstant;
import cn.iocoder.yudao.module.ai.controller.admin.datasetversion.vo.DatasetQualityTaskSaveReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.datasetversion.vo.DatasetVersionSaveReqVO;
import cn.iocoder.yudao.module.ai.dal.dataobject.datasetmark.DatasetMarkDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.datasetreleasefile.DatasetReleaseFileDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.materialreleasefile.MaterialReleaseFileDO;
import cn.iocoder.yudao.module.ai.dal.mysql.datasetmark.DatasetMarkMapper;
import cn.iocoder.yudao.module.ai.dal.mysql.datasetreleasefile.DatasetReleaseFileMapper;
import cn.iocoder.yudao.module.ai.service.datasetmark.DatasetMarkService;
import cn.iocoder.yudao.module.ai.service.datasetreleasefile.DatasetReleaseFileService;
import cn.iocoder.yudao.module.ai.service.datasetversion.DatasetVersionService;
import cn.iocoder.yudao.module.ai.utils.DataSetUtil;
import cn.iocoder.yudao.module.ai.utils.vo.DataSetFileVo;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;

import cn.iocoder.yudao.module.ai.controller.admin.dataset.vo.*;
import cn.iocoder.yudao.module.ai.dal.dataobject.dataset.DatasetDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.ai.dal.mysql.dataset.DatasetMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.*;

/**
 * 数据集管理 Service 实现类
 *
 * @author 侯俊青
 */
@Slf4j
@Service
@Validated
public class DatasetServiceImpl implements DatasetService {

    @Resource
    private DatasetMapper datasetMapper;
    @Resource
    private DatasetVersionService datasetVersionService;
    @Resource
    private DatasetReleaseFileService datasetReleaseFileService;
    @Resource
    private DatasetReleaseFileMapper datasetReleaseFileMapper;
    @Resource
    private DatasetMarkService datasetMarkService;
    @Resource
    private DatasetMarkMapper datasetMarkMapper;

    @Resource
    private DataSetUtil dataSetUtil;
    @Resource
    private DeptApi deptApi ;
    /**
     * 公共-上传到本地文件的路径
     */
    @Value("${yudao.file.upload-path}")
    private String commonUploadPath;

    @Override
    public Long updateDataset(DatasetUpdateReqVO saveReqVO) {
        DatasetSaveReqVO updateReqVO = BeanUtils.toBean(saveReqVO, DatasetSaveReqVO.class);
        return saveDataset(updateReqVO);
    }

    @Override
    public Long uploadFile(DatasetUploadFileReqVO saveReqVO) {
        DatasetSaveReqVO updateReqVO = BeanUtils.toBean(saveReqVO, DatasetSaveReqVO.class);
        return saveDataset(updateReqVO);
    }

    public Long saveDataset(DatasetSaveReqVO saveReqVO) {

        // 验证业务字典值
        checkBizValue("标注场景",DicConstant.key_dataset_mark_file_type,saveReqVO.getFileType());
        checkBizValue("标注类型",DicConstant.key_dataset_mark_biz_type,saveReqVO.getSenceType());
        checkBizValue("所属行业",DicConstant.key_Industry_affiliation,saveReqVO.getIndustryId());
        checkBizValue("所属行业（模型大类）",DicConstant.key_model_broad_category,saveReqVO.getIndustryId2());
        checkBizValue("所属行业（模型小类）",DicConstant.key_model_subclass,saveReqVO.getIndustryId3());
        // 什么也没有上传,只更新基础信息后返回
        if(null != saveReqVO.getId()){
            // 保存基本信息后返回
            DatasetDO oldDataSet = datasetMapper.selectById(saveReqVO.getId());
            // 非上传文件
            if(null == saveReqVO.getFile() && StringUtils.isBlank(saveReqVO.getAbsDiskFilePath())){
                oldDataSet.setName(saveReqVO.getName());
                oldDataSet.setDescription(saveReqVO.getDescription());
                oldDataSet.setFileType(saveReqVO.getFileType());
                oldDataSet.setSenceType(saveReqVO.getSenceType());
                oldDataSet.setIndustryId(saveReqVO.getIndustryId());
                oldDataSet.setIndustryId2(saveReqVO.getIndustryId2());
                oldDataSet.setIndustryId3(saveReqVO.getIndustryId3());
                oldDataSet.setLabelInfo(saveReqVO.getLabelInfo());
                datasetMapper.updateById(oldDataSet);
                return saveReqVO.getId();
            }else{
                // 仅上传文件、其他信息仍然使用旧的数据
                saveReqVO.setName(oldDataSet.getName());
                saveReqVO.setDescription(oldDataSet.getDescription());
                saveReqVO.setFileType(oldDataSet.getFileType());
                saveReqVO.setSenceType(oldDataSet.getSenceType());
                saveReqVO.setIndustryId(oldDataSet.getIndustryId());
                saveReqVO.setIndustryId2(oldDataSet.getIndustryId2());
                saveReqVO.setIndustryId3(oldDataSet.getIndustryId3());
                saveReqVO.setLabelInfo(oldDataSet.getLabelInfo());
            }
        }

        // 有上传文件
        DatasetDO dataset = BeanUtils.toBean(saveReqVO, DatasetDO.class);
        dataset.setSuplierId(deptApi.queryFirstDept(SecurityFrameworkUtils.getLoginUserDeptId()));

        if(null != saveReqVO.getFile() && StringUtils.isNotBlank(saveReqVO.getAbsDiskFilePath())){
            throw new BusinessException("不能同时上传文件和设置本地文件路径");
        }
        if(null == saveReqVO.getFile()){
            if(StringUtils.isBlank(saveReqVO.getAbsDiskFilePath())){
                throw new BusinessException("上传文件和本地文件路径不能同时为空");
            }else{
                File f = null;
                try {
                    f = new File(commonUploadPath+saveReqVO.getAbsDiskFilePath());
                } catch (Exception e) {
                    log.error("读取本地文件失败，commonUploadPath={},filePath={}",commonUploadPath,saveReqVO.getAbsDiskFilePath());
                    throw new BusinessException("读取文件失败，请重试设置路径");
                }
                if(f.exists() && f.isFile() &&
                        (f.getAbsolutePath().endsWith("zip") || f.getAbsolutePath().endsWith("ZIP"))){
                    if(f.length() > (1024*1024*1024)){
                        throw new BusinessException("文件太大，请上传不大于1G的文件");
                    }
                    dataset.setFileSize(f.length());
                    dataset.setFileOriginalName(f.getName());
                }else{
                    throw new BusinessException("上传文件不存在或者不是压缩包");
                }
            }
        }else{
            if(saveReqVO.getFile().getSize() > (1024*1024*1024)){
                throw new BusinessException("文件太大，请上传不大于1G的文件");
            }
            dataset.setFileSize(saveReqVO.getFile().getSize());
            dataset.setFileOriginalName(saveReqVO.getFile().getOriginalFilename());
        }

        // 保存zip文件
        String[] savePathArr ;
        try {
            savePathArr = dataSetUtil.saveZipFile(saveReqVO.getFile(), new File(commonUploadPath+saveReqVO.getAbsDiskFilePath()));
            dataset.setFileUploadPath(savePathArr[0]);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 解压zip文件
        List<DataSetFileVo> releaseFileList = null;
        try {
            releaseFileList = dataSetUtil.datasetFileUncompressing(savePathArr[1], savePathArr[3]);
        } catch (IOException e) {
            log.error("解压文件出现异常，保存失败",e);
            throw new BusinessException("解压文件出现异常，保存失败");
        }
        Long totalDuration = 0L;

        // 标签文件
        DatasetReleaseFileDO targetClassesFile = null;
        // 原始文件 和标注文件的对应关系
        List<Triple<DatasetReleaseFileDO, DatasetReleaseFileDO,DataSetFileVo>> pairList = new ArrayList<>();
        // 未进行标注的原始文件
        List<DatasetReleaseFileDO> noMarkOriginalList = new ArrayList<>();
        // 播放总时长
        Long totolDuration = 0L;
        // 原始文件总个数
        Long totolOriginalFileNum = 0L;
        // 原始文件总个数
        Long totolMarkFileNum = 0L;

        if(CollectionUtils.isNotEmpty(releaseFileList)){
            // 文件顺序
            int releaseFileIndex = 0 ;
            // 标签分类
            List<String> labelNameClassesList = new ArrayList<>();

            // 1. 先找 classes 文件处理
            for (int i = 0; i < releaseFileList.size(); i++) {
                // 找到 classes 文件
                DataSetFileVo dataSetFileVo = releaseFileList.get(i);
                // 解析标签文件
                if(dataSetFileVo.getOriginalFileName().toLowerCase().endsWith("classes.txt")){
                    // 保存文件
                    DatasetReleaseFileDO releaseFileDO = new DatasetReleaseFileDO();
                    releaseFileDO.setFileType(saveReqVO.getFileType());
                    releaseFileDO.setFileOriginalName(dataSetFileVo.getOriginalFileName());
                    releaseFileDO.setFileSize(dataSetFileVo.getFile().length());
                    releaseFileDO.setFileUploadPath(savePathArr[2]+dataSetFileVo.getFileName());
                    releaseFileDO.setSortNum(releaseFileIndex);
                    releaseFileDO.setFileBizType(3);
                    targetClassesFile = releaseFileDO ;

                    // 最大读取1000行，再多就说明有问题，不读了
                    int maxLine = 1000;
                    int lineNum = 0;

                    try {
                        BufferedReader reader = new BufferedReader(new FileReader(dataSetFileVo.getFile()));
                        String line;
                        while ((line = reader.readLine()) != null) {
                            lineNum++ ;
                            if (lineNum > maxLine){
                                break;
                            }
                            if(StringUtils.isNotBlank(line)){
                                labelNameClassesList.add(line.trim());
                            }
                        }
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                        log.error("读取classes.txt文件出现异常，保存失败",e);
                        throw new BusinessException("读取classes.txt文件出现异常，保存失败");
                    }
                    // 设置标签分类信息
                    dataset.setMarkFileClasses(JSONArray.toJSONString(labelNameClassesList));
                    releaseFileList.remove(i);
                    break;
                }
            }

            //
            for (int i = 0; i < releaseFileList.size(); i++) {
                DataSetFileVo dataSetFileVo = releaseFileList.get(i);
                String oriName = dataSetFileVo.getOriginalFileName();
                String fileName = oriName.substring(0,oriName.length() - dataSetFileVo.getExtension().length());
                if(!dataSetFileVo.getOriginalFileName().toLowerCase().endsWith(".txt")){
                    // 原始文件
                    DatasetReleaseFileDO releaseFileDO = new DatasetReleaseFileDO();
                    releaseFileDO.setFileType(saveReqVO.getFileType());
                    releaseFileDO.setFileOriginalName(dataSetFileVo.getOriginalFileName());
                    releaseFileDO.setFileSize(dataSetFileVo.getFile().length());
                    releaseFileDO.setFileUploadPath(savePathArr[2]+dataSetFileVo.getFileName());
                    releaseFileDO.setSortNum(releaseFileIndex);
                    releaseFileDO.setFileBizType(1);
                    releaseFileDO.setDuration(dataSetUtil.getMp4Seconds(dataSetFileVo.getFile().getAbsolutePath()).longValue());
                    releaseFileList.remove(i);
                    totolDuration = totolDuration + releaseFileDO.getDuration();
                    totolOriginalFileNum = totolOriginalFileNum + 1;
                    i-- ;
                    // 找标注文件
                    boolean isFindMark = false ;
                    for (int j = 0; j < releaseFileList.size(); j++) {
                        DataSetFileVo dataSetFileVo1 = releaseFileList.get(j);
                        String markFileName = fileName.toLowerCase() +"txt";
                        if(dataSetFileVo1.getOriginalFileName().toLowerCase().endsWith(markFileName)){
                            // 找到了标注文件
                            DatasetReleaseFileDO remarkFileDO = new DatasetReleaseFileDO();
                            remarkFileDO.setFileType(saveReqVO.getFileType());
                            remarkFileDO.setFileOriginalName(dataSetFileVo1.getOriginalFileName());
                            remarkFileDO.setFileSize(dataSetFileVo1.getFile().length());
                            remarkFileDO.setFileUploadPath(savePathArr[2]+dataSetFileVo1.getFileName());
                            remarkFileDO.setSortNum(releaseFileIndex);
                            remarkFileDO.setFileBizType(2);
                            pairList.add(Triple.of(releaseFileDO, remarkFileDO,dataSetFileVo1));
                            releaseFileList.remove(j);
                            isFindMark = true ;
                            totolMarkFileNum++;
                            break;
                        }
                    }

                    // 没有找到，放到原始文件中
                    if (!isFindMark){
                        noMarkOriginalList.add(releaseFileDO);
                    }
                }
            }
            // 剩余的文件，不知道是什么，按照原始文件存储
            for (int i = 0; i < releaseFileList.size(); i++) {
                DataSetFileVo dataSetFileVo = releaseFileList.get(i);
                // 原始文件
                DatasetReleaseFileDO releaseFileDO = new DatasetReleaseFileDO();
                releaseFileDO.setFileType(saveReqVO.getFileType());
                releaseFileDO.setFileOriginalName(dataSetFileVo.getOriginalFileName());
                releaseFileDO.setFileSize(dataSetFileVo.getFile().length());
                releaseFileDO.setFileUploadPath(savePathArr[2]+dataSetFileVo.getFileName());
                releaseFileDO.setSortNum(releaseFileIndex);
                releaseFileDO.setFileBizType(1);
                releaseFileDO.setDuration(dataSetUtil.getMp4Seconds(dataSetFileVo.getFile().getAbsolutePath()).longValue());
                totolDuration = totolDuration + releaseFileDO.getDuration();
                totolMarkFileNum++;
                noMarkOriginalList.add(releaseFileDO);
            }
        }else{
            throw new BusinessException("未能从压缩包中解析到文件，操作失败");
        }

        // 设置汇总信息
        dataset.setDuration(totalDuration);
        dataset.setContainFileNum(totolOriginalFileNum.intValue());
        dataset.setMarkFileNum(totolMarkFileNum.intValue());
        if(null != dataset.getContainFileNum() && dataset.getContainFileNum().equals(dataset.getMarkFileNum())){
            dataset.setMarkStatus(DicConstant.dataset_mark_status_complete);
        }else{
            dataset.setMarkStatus(DicConstant.dataset_mark_status_ing);
        }
        // 重置质检任务 和 质检文件 和 发版状态
        dataset.setQualityUserId("");
        dataset.setQualityTime(null);
        dataset.setQualityFileNum(0);

        dataset.setQualityTaskName(null);
        dataset.setQualityTaskDescription(null);
        dataset.setQualityTaskFlag(DicConstant.dataSet_quality_task_flag_not_start);
        dataset.setQualityTaskUserId(null);
        dataset.setQualityTaskCreateTime(null);

        dataset.setQualityStatus(DicConstant.dataSet_quality_status_not_start);
        dataset.setPublishStatus(DicConstant.dataSet_publish_status_not_start);
        // 是修改
        if(null != saveReqVO.getId()){
            // 先删除关联的记录
            datasetReleaseFileService.deleteByDatasetId(saveReqVO.getId());
            datasetMarkService.deleteByDatasetId(saveReqVO.getId());
            datasetMapper.updateById(dataset);
        }else{
            // 新增
            datasetMapper.insert(dataset);
        }

        //======== 开始保存文件记录 ==================
        // 保存classes文件
        targetClassesFile.setDatasetId(dataset.getId());
        targetClassesFile.setSortNum(0);
        datasetReleaseFileMapper.insert(targetClassesFile);
        // 保存 有标注的 原始文件和标注文件
        AtomicInteger relaeseFileIndex = new AtomicInteger();
        pairList.forEach(pair -> {
            relaeseFileIndex.getAndIncrement();
            DatasetReleaseFileDO mark = pair.getMiddle();
            mark.setDatasetId(dataset.getId());
            mark.setSortNum(relaeseFileIndex.get());
            datasetReleaseFileMapper.insert(mark);
            DatasetReleaseFileDO original = pair.getLeft();
            original.setDatasetId(dataset.getId());
            original.setMarkFileId(mark.getId());
            original.setSortNum(relaeseFileIndex.get());
            original.setMarkFileOriginalName(mark.getFileOriginalName());
            original.setMarkFileUploadPath(mark.getFileUploadPath());
            original.setMarkFileSize(mark.getFileSize());
            datasetReleaseFileMapper.insert(original);
            // 解析标注信息
            List<DatasetMarkDO> markDOList = new ArrayList<>();
            DataSetFileVo fileVo = pair.getRight();
            // 最大读取10000行，再多就说明有问题，不读了
            int maxLine = 10000;
            int lineNum = 0;
            BufferedReader reader = null ;
            try {
                reader = new BufferedReader(new FileReader(fileVo.getFile()));
                int rowIndex = 0 ;
                String line;
                while ((line = reader.readLine()) != null) {
                    lineNum++ ;
                    if (lineNum > maxLine){
                        break;
                    }
                    if(StringUtils.isNotBlank(line)){
                        DatasetMarkDO datasetMarkDO = new DatasetMarkDO();
                        datasetMarkDO.setDatasetId(dataset.getId());
                        datasetMarkDO.setMarkFileId(mark.getId());
                        datasetMarkDO.setMarkOriginalFileId(original.getId());
                        String[] split = line.trim().split(" ");
                        datasetMarkDO.setLabelIndex(Integer.parseInt(split[0]));
                        List<String> contentList  = new ArrayList<>();
                        for (int i = 1; i < split.length; i++) {
                            contentList.add(split[i]);
                        }
                        datasetMarkDO.setMarkContent(JSONArray.toJSONString(contentList));
                        rowIndex++ ;
                        datasetMarkDO.setSortNum(rowIndex);
                        markDOList.add(datasetMarkDO);
                    }
                }

            } catch (IOException e) {
                e.printStackTrace();
                log.error("读取classes.txt文件出现异常，保存失败",e);
                throw new BusinessException("读取classes.txt文件出现异常，保存失败");
            }finally {
                try {
                    reader.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(CollectionUtils.isNotEmpty(markDOList)){
                datasetMarkMapper.insertBatch(markDOList);
            }
        });
        // 保存未找到标注的文件
        if(CollectionUtils.isNotEmpty(noMarkOriginalList)){
            for (int i = 0; i < noMarkOriginalList.size(); i++) {
                relaeseFileIndex.incrementAndGet();
                noMarkOriginalList.get(i).setDatasetId(dataset.getId());
                noMarkOriginalList.get(i).setSortNum(relaeseFileIndex.get());
            }
            datasetReleaseFileMapper.insertBatch(noMarkOriginalList);
        }
        return dataset.getId();
    }

    /**
     * 验证 业务字典值 是否正确
     * @param bizKey
     * @param bizValue
     */
    private void checkBizValue(String bizName,String bizKey,String bizValue) {
        if(StringUtils.isNotBlank(bizValue) && StringUtils.isNotBlank(bizKey)){
            String dictDataLabel = DictFrameworkUtils.getDictDataLabel(bizKey, bizValue);
            if(null == dictDataLabel){
                throw new BusinessException(bizName+"设置不正确");
            }
        }
    }

//    @Override
//    public Long createDataset(DatasetSaveReqVO createReqVO) {
//        // 插入
//        DatasetDO dataset = BeanUtils.toBean(createReqVO, DatasetDO.class);
//        datasetMapper.insert(dataset);
//        // 返回
//        return dataset.getId();
//    }
//
//    @Override
//    public void updateDataset(DatasetSaveReqVO updateReqVO) {
//        // 校验存在
//        validateDatasetExists(updateReqVO.getId());
//        // 更新
//        DatasetDO updateObj = BeanUtils.toBean(updateReqVO, DatasetDO.class);
//        datasetMapper.updateById(updateObj);
//    }

    @Override
    public void deleteDataset(Long id) {
        // 校验存在
        validateDatasetExists(id);
        // 删除
        datasetMapper.deleteById(id);
    }

    private void validateDatasetExists(Long id) {
        if (datasetMapper.selectById(id) == null) {
            throw exception(DATASET_NOT_EXISTS);
        }
    }

    @Override
    public DatasetDO getDataset(Long id) {
        return datasetMapper.selectById(id);
    }

    @Override
    public PageResult<DatasetDO> getDatasetPage(DatasetPageReqVO pageReqVO) {
        return datasetMapper.selectPage(pageReqVO);
    }

    @Override
    public Map<Long, DatasetReleaseFileDO> getFirstFileMap(List<Long> datasetIdList) {
        LambdaQueryWrapper<DatasetReleaseFileDO> doList = new LambdaQueryWrapper<DatasetReleaseFileDO>();
        doList.in(DatasetReleaseFileDO::getDatasetId, datasetIdList);
        doList.eq(DatasetReleaseFileDO::getFileBizType, 1);
        doList.eq(DatasetReleaseFileDO::getSortNum, 1);
        List<DatasetReleaseFileDO> datasetReleaseFileDOS = datasetReleaseFileMapper.selectList(doList);
        if(CollectionUtils.isNotEmpty(datasetReleaseFileDOS)){
            return datasetReleaseFileDOS.stream().collect(Collectors.toMap(DatasetReleaseFileDO::getDatasetId, Function.identity(), (v1, v2) -> v1));
        }
        return new HashMap<>();
    }

    @Override
    public void updateFileQuality(DatasetFileQualityReqVO datasetFileQualityReqVO) {
        DatasetReleaseFileDO datasetReleaseFileDO = datasetReleaseFileMapper.selectById(datasetFileQualityReqVO.getOriginalFileId());
        if(null != datasetFileQualityReqVO.getQualityStauts()){
            if(!DicConstant.dataSet_file_biz_type_original.equals(datasetReleaseFileDO.getFileBizType())){
                throw new BusinessException("文件类型不是待标注文件，不能设置质检状态");
            }
            DatasetDO datasetDO = datasetMapper.selectById(datasetReleaseFileDO.getDatasetId());
            // 未创建质检任务，且质检文件未开始，不能进行质检
            if(!DicConstant.dataSet_quality_task_flag_finish.equals(datasetDO.getQualityTaskFlag())
                && DicConstant.dataSet_quality_status_not_start.equals(datasetReleaseFileDO.getQualityStatus())){
                throw new BusinessException("质检任务未创建，不能修改文件质检状态");
            }
            if(DicConstant.dataSet_publish_status_pass.equals(datasetDO.getPublishStatus())){
                throw new BusinessException("数据集已发布，不能修改质检状态");
            }

            if(!datasetDO.getContainFileNum().equals(datasetDO.getMarkFileNum())){
                throw new BusinessException("数据集标注不全，不能修改质检状态");
            }

            datasetReleaseFileDO.setQualityStatus(datasetFileQualityReqVO.getQualityStauts());
            datasetReleaseFileDO.setQualityUserId(""+SecurityFrameworkUtils.getLoginUserId());
            datasetReleaseFileDO.setQualityTime(LocalDateTime.now());
            datasetReleaseFileMapper.updateById(datasetReleaseFileDO);

            // 更新统计信息
            LambdaQueryWrapper<DatasetReleaseFileDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DatasetReleaseFileDO::getDatasetId, datasetReleaseFileDO.getDatasetId());
            queryWrapper.eq(DatasetReleaseFileDO::getFileBizType, DicConstant.dataSet_file_biz_type_original);
            queryWrapper.in(DatasetReleaseFileDO::getQualityStatus, DicConstant.dataSet_quality_status_pass);
            Long successCount = datasetReleaseFileMapper.selectCount(queryWrapper);
            queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DatasetReleaseFileDO::getDatasetId, datasetReleaseFileDO.getDatasetId());
            queryWrapper.eq(DatasetReleaseFileDO::getFileBizType, DicConstant.dataSet_file_biz_type_original);
            queryWrapper.in(DatasetReleaseFileDO::getQualityStatus, DicConstant.dataSet_quality_status_not_pass);
            Long failCount = datasetReleaseFileMapper.selectCount(queryWrapper);
            Integer allCount = successCount.intValue() + failCount.intValue() ;

            // 更新标注文
            datasetDO.setQualityFileNum(allCount);
            if(null == datasetDO.getQualityTime()){
                datasetDO.setQualityTime(LocalDateTime.now());
            }
            if(null == datasetDO.getQualityUserId()){
                datasetDO.setQualityUserId(""+SecurityFrameworkUtils.getLoginUserId());
            }

            // 质检中
            if(datasetDO.getContainFileNum() > allCount){
                datasetDO.setQualityStatus(DicConstant.dataSet_quality_status_ing);
            }
            // 全部标注完成
            else if(datasetDO.getContainFileNum().equals(allCount) ){
                if(failCount > 0L){
                    // 总体质检不合格
                    datasetDO.setQualityStatus(DicConstant.dataSet_quality_status_not_pass);
                }else{
                    // 总体质检合格
                    datasetDO.setQualityStatus(DicConstant.dataSet_quality_status_pass);
                }
            }
            datasetMapper.updateById(datasetDO);
        }
    }

    @Override
    public void publish(DatasetVersionSaveReqVO datasetVersionSaveReqVO) {
        DatasetDO dataset = getDataset(datasetVersionSaveReqVO.getDatasetId());
        if(null == dataset){
            throw new BusinessException("数据不存在");
        }
        if(StringUtils.isBlank(dataset.getQualityStatus())
            || DicConstant.dataSet_quality_status_not_start.equals(dataset.getQualityStatus())
            || DicConstant.dataSet_quality_status_ing.equals(dataset.getQualityStatus())){
            throw new BusinessException("质检未完成，不能发布版本");
        }
        dataset.setPublishStatus(DicConstant.dataSet_publish_status_pass);
        // 更新发版状态
        datasetMapper.updateById(dataset);
        datasetVersionService.createDatasetVersion(datasetVersionSaveReqVO);
    }

    @Override
    public void createQualityTask(DatasetQualityTaskSaveReqVO datasetQualityTaskSaveReqVO) {
        DatasetDO dataset = getDataset(datasetQualityTaskSaveReqVO.getDatasetId());
        if(null == dataset){
            throw new BusinessException("数据不存在");
        }
        if(!DicConstant.dataset_mark_status_complete.equals(dataset.getMarkStatus())){
            throw new BusinessException("标注未完成，不能创建质检任务");
        }
        if(!DicConstant.dataSet_quality_status_not_start.equals(dataset.getQualityStatus())){
            if(!DicConstant.dataSet_quality_task_flag_finish.equals(dataset.getQualityTaskFlag())){
                throw new BusinessException("质检已经进行中或者结束，不能重复创建质检任务");
            }
            throw new BusinessException("质检已经进行中或者结束，不能创建质检任务");
        }
        dataset.setQualityTaskName(datasetQualityTaskSaveReqVO.getName());
        dataset.setQualityTaskDescription(datasetQualityTaskSaveReqVO.getDescription());
        dataset.setQualityTaskCreateTime(LocalDateTime.now());
        dataset.setQualityTaskUserId(""+SecurityFrameworkUtils.getLoginUserId());
        dataset.setQualityTaskFlag(DicConstant.dataSet_quality_task_flag_finish);
        // 更新质检任务状态
        datasetMapper.updateById(dataset);
    }
}